﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using Game.Foundation;
using MF.Networker;

namespace Server.Major
{
    class Connection : IDisposable
    {
        public static readonly int ActiveSeconds = 45;

        private AsyncWorkSocket _netWorker;

        public ConnectType ConnectType { get; private set; }

        public string Name { get; private set; }

        public event EventHandler<GameConfigEventArgs> ReceivedRegisterGameServerRequest;
        public event EventHandler<LogoutGameServerEventArgs> ReceivedLogoutGameServerRequest;
        public event EventHandler ReceivedGameListRequest;

        public Connection(Socket client)
        {
            //this.OverdueTime = DateTime.Now.AddSeconds(ActiveSeconds);
            this._netWorker = new AsyncWorkSocket(client, GamePacketLoader.Default);
            this._netWorker.PacketReceived += new EventHandler<PacketEventArgs>(_netWorker_PacketReceived);
            this.ConnectType = ConnectType.Default;
        }

        public void SendMessage(IPacket packet)
        {
            this._netWorker.SendAsync(packet);
        }

        public void SendMessage(IEnumerable<IPacket> packetList)
        {
            this._netWorker.SendAsync(packetList);
        }

        void _netWorker_PacketReceived(object sender, PacketEventArgs e)
        {
            GamePacket p = e.Packet as GamePacket;

            switch (p.Type)
            {
                case PacketType.Pong:
                    //this.OverdueTime = DateTime.Now.AddSeconds(ActiveSeconds);
                    break;

                case PacketType.注册游戏处理程序:
                    ProcessRegisterGameServer(p);
                    break;

                case PacketType.注销游戏处理程序:
                    ProcessLogoutGameServer(p);
                    break;

                case PacketType.游戏列表请求包:
                    ProcessGameListRequest(p);
                    break;
            }
        }

        private void ProcessRegisterGameServer(GamePacket translater)
        {
            this.ConnectType = ConnectType.GameServer;

            if (this.ReceivedRegisterGameServerRequest == null) return;

            GameConfigEventArgs e = new GameConfigEventArgs();
            GameConfig game = new GameConfig();
            game.Name = translater.ReadString();
            game.IPAddress = translater.ReadString();
            game.Port = translater.ReadInt32();
            game.SeatCount = translater.ReadInt32();
            game.RelativePath = translater.ReadString();
            game.DownloadPath = translater.ReadString();
            int areaCount = translater.ReadInt32();
            for (int i = 0; i < areaCount; i++)
            {
                GameAreaConfig area = new GameAreaConfig();
                area.ID = translater.ReadInt32();
                area.Name = translater.ReadString();
                int roomCount = translater.ReadInt32();

                for (int j = 0; j < roomCount; j++)
                {
                    GameRoomConfig room = new GameRoomConfig();
                    room.ID = translater.ReadInt32();
                    room.Name = translater.ReadString();

                    area.RoomList.Add(room);
                }

                game.AreaList.Add(area);
            }
            e.GameConfig = game;

            this.ReceivedRegisterGameServerRequest(this, e);

        }

        private void ProcessLogoutGameServer(GamePacket p)
        {
            if (this.ReceivedLogoutGameServerRequest == null) return;

            LogoutGameServerEventArgs e = new LogoutGameServerEventArgs();
            e.GameName = p.ReadString();
            this.ReceivedLogoutGameServerRequest(this, e);
        }

        private void ProcessGameListRequest(GamePacket p)
        {
            this.ConnectType = ConnectType.GameClient;

            if (this.ReceivedGameListRequest != null)
            {
                this.ReceivedGameListRequest(this, EventArgs.Empty);
            }
        }

        #region IDisposable 成员

        public void Dispose()
        {
            this._netWorker.Close();
            Console.WriteLine(string.Format("{0}[{1}]的连接已关闭。", this.ConnectType == ConnectType.GameClient ? "玩家" : "游戏", this.Name));
        }

        #endregion
    }

    enum ConnectType
    {
        Default,
        GameClient,
        GameServer,
    }
}
